Fork me on GitHub

基于开源URL数据字符串特征的恶意性检测,本科毕业设计

最近整理了一下本科的毕业设计(2018年6月完成的),代码发布于https://github.com/metang326/malicious-URL-detection

URL异常检测本质上是一个分类问题,将输入的URL经过处理后得到特征,输入到分类其中,分类器输出分类结果,恶意的还是良性的。
在训练集和验证集的基础上训练了多个分类模型,训练集用于训练、验证集用来调整参数。

特征提取

数据预处理

首先,鉴于只有小部分URL的前缀有“http”,“https”以及“www”字段,并且这些字符对于恶意性检测并没有帮助,所以在预处理阶段我们将这些前缀删去。

但是要注意将前缀部分与其他部分出现的“http”等字段进行区分,如:“zylights.com/img/?us.battle.net/login/en/?ref=http%3A%2F%2Fkhcdcofus.battle.net%2Fd3%2Fen%2Findex&app=com-d3”中的“http”就出现在参数部分。

此外,由于URL的参数字段可能存在恶意代码,所以我们还需要对URL的编码问题进行考虑,以免影响检测的效果,比如参数字段中的“%20”代表的是空格。

URL结构划分

考虑到黑名单特征和主机特征的获取非常耗时,并且还会存在一定的噪声和缺失值,而基于内容的特征又非常“重量级”,并且在下载网页内容的过程中会给系统带来安全威胁。

因此,我们选择了基于词汇的URL特征,在能够取得较好检测效果的同时又可以保证“轻量级”和高安全性。为此,我们需要对URL进行深入的了解,URL的结构样例。

1
2
3
4
5
6
7
8
9
10
11
例如:
http://www.aspxfans.com:8080/news/index.asp?boardID=5&ID=24618&page=1#name
1.协议部分:“http:”,在Internet中有多种网络协议例如:http:, https:, ftp: 等。后面的“//“为分隔符
2.域名部分:“www.aspxfans.com”是url的域名部分,在Url中也可以使用ip地址作为域名使用
3.端口部分:跟在域名后面的成为端口,域名和端口之间使用“:”进行分割,端口不是Url的必须部分可以省略
4.虚拟目录部分:从域名后面的第一个"/"开始到最后一个“/‘截止称之为虚拟目录部分,虚拟目录也不是Url的必须部分,本次实例的虚拟目录是”/news/“
5.文件名部分:从域名后的最后一个"/"开始到"?"为止成为文件名部分,如果没有"?"则从域名后的最后一个"/"开始到"#"为止是文件部分,如果没有"?"和”#“,那么从域名后的最后一个"/"开始到结束,都是文件名部分,本例的文件名部分是”index.asp“。文件名部分也不是URl的必须部分,如果省略该部分则使用默认的文件名
6.锚部分:从”#“开始到最后,都是锚部分,本例中的锚部分是”name“,锚部分也不是一个url的必须部分。
7.参数部分:从"?"开始到"#"为止之间的部分成为参数部分,又称搜索部分,查询部分本例中的”boardID=5&ID=24618&page=1“称为参数部分参数部分允许有多个参数,参数与参数之间用"&"作为分隔符。
[URL结构讲解内容参考链接:https://www.jianshu.com/p/b35a94bafb96]

提取内容列表

由于协议部分对恶意URL的检测没有明显帮助,所以我们不考虑提取这部分作为特征。

在提取特征时,一条URL可以被分成域名、路径、查询参数、锚点四大部分,每个部分又分别是由数字、字母以及特殊符号构成的,我们可以根据特殊字符(例如“/”,“.”,“?”,“=”等)将URL切分为不同的token。这样,我们就可以将一条URL看作是由一组token组成的向量,从而获取到更加具体的特征。

针对URL整体以及它的每个部分,我们一共提取了85个特征,分为基于URL整体的特征、基于域名的特征、基于路径的特征、基于查询参数的特征以及基于锚点的特征。

其中的“恶意词出现次数”特征所统计的恶意词是根据malwaredomains.com下载的恶意域数据集(和训练集、验证集、测试集没有交集)统计出现次数较多的词。
Python自带的包可以根据恶意词的统计结果生成的词云图片,其中字体较大的数据出现频率更高。可以看出,“beget”“service”, “account”, “eby”, “paypal”, “login”, “confirm”这类词出现的频率很高,因为恶意网站经常模仿良性网站或者用一些有吸引力的词语,试图诱导用户输入账号以及登陆信息。

流行网站名是根据Alexa排名前500名的网站数据集进行统计得到的,有些恶意网站会通过模仿知名网站来迷惑用户。根据流行网站中出现的词,我们生成了词云后发现,流行词与恶意词存在着部分交集,比如“apple”、“google”、“facebook”这些词,因为恶意网站有时会假冒流行网站,选取相近的域名来迷惑用户。

所提取的全部特征见下表:

基于整体URL的特征 基于hostname的特征 基于path的特征 基于search的特征 基于hash的特征
URL长度 token个数 token个数 token个数 token个数
字母比例 特殊字符个数 path长度 search长度
数字比例 字母比例 目录深度(/) 参数个数(&)
特殊符号的种类个数 数字比例 最长token 方差
特殊字符个数 出现点的次数(.) 特殊符号的种类个数
URL深度(/) 是否是IP地址 方差
出现点的次数(.)
存在@符号 token方差
顶级域名TLD hostname长度
出现恶意词的次数 字母出现次数
出现流行网站名的次数
出现.php或者.exe的次数
在除了开头位置出现http,www的次数
字母出现次数

特征分析

为了分析我们所选取的特征是否可以对恶意URL进行有效地检验,我们比较了恶意URL和良性URL在不同特征下的平均值。

在随机划分情况下,不同的子集上相同特征的平均值几乎相同,仅有非常微小的区别。然而,当以标签作为划分依据之后,可以看出恶意URL集和良性URL集在相同特征下,平均值有明显的差异。

基于整体URL的特征 恶意URL平均值 良性URL平均值
URL长度 55.78 47
字母比例 0.79 0.79
数字比例 0.075 0.06
特殊符号的种类个数 0.94 1.03
特殊字符个数 2.07 2.58
URL深度(/) 2.78 2.32
出现点的次数(.) 2.219 1.66
存在@符号 0.022 0
出现恶意词的次数 2.617 1.44
出现流行网站名的次数 0.922 0.67
出现.php或者.exe的次数 0.279 0.04
在除了开头位置出现http,www的次数 0.039 0
基于hostname的特征 恶意URL平均值 良性URL平均值
token个数 2.48 2.35
特殊字符个数 0.15 0.06
字母比例 0.887 0.9
数字比例 0.022 0.006
出现点的次数(.) 1.346 1.29
3.398 3.31
token方差 3.943 3.2
hostname长度 15.8 14.36
基于path的特征 恶意URL平均值 良性URL平均值
token个数 3.48 4.25
path长度 21.466 23.18
目录深度(/) 1.739 1.31
最长token 1.57 0.92
特殊符号的种类个数 0.795 0.97
方差 2.27 1.71
基于search的特征 恶意URL平均值 良性URL平均值
token个数 1.46 0.56
search长度 11.04 2.75
参数个数(&) 0.27 0.076
方差 1.05 0.37

模型训练

在提取特征的基础上,使用sklearn库中自带的分类模型在训练集上进行模型训练,根据各个分类器在验证集上的效果,在投票时设置了不同的权重。精确率高的分类器权重更高,也就是我们认为它的结果更加可信。

阈值在代码里的设置是,随机森林或者梯度提升树中只要有一个认为URL是恶意的,那就是恶意的,因为这两个模型的准确率比较高。剩下的四个分类器需要同时认为该URL是恶意的时候 才认为它是恶意的

实验结果

从kdnuggets上收集到了带标签(good/bad)的URL数据集,共416350条,其中异常数据(bad)71556条,占比17.19%;
正常数据(good)344794条,占比82.81%。

将全体数据划分为训练集(70%),验证集(15%)和测试集(15%),并且在每个集合中均保持异常数据所占比例相同。

分类器模型 准确度(%) 精确度(%) 召回率(%)
贝叶斯 85.88 60.82 50.25
AdaBoost 92.84 86.05 69.65
随机森林 97.13 95.9 87.05
决策树 94.63 83.9 85.11
逻辑回归 90.86 83.29 58.58
梯度提升树 96.35 93.7 84.45
基于投票的分类器 97.1 92.51 90.48
-------------本文结束感谢您的阅读-------------